#include "DebugRendererGL.h"
#include "IBoundary2.h"
#include "IDomain2.h"
#include "Allocator.h"

#ifdef WIN32 
#include <windows.h>
#endif
#include <GL/gl.h>


DebugRendererGL::DebugRendererGL(Scalar tolerance, IStackAllocator& stack)
	: tolerance_(tolerance), stack_(&stack)
{
}

void DebugRendererGL::render(const IBounded2& domain, const Vector2& translation)
{
	renderWire(domain, translation);
}

void DebugRendererGL::renderFill(const IBounded2& domain, const Vector2& translation)
{
	::glPushMatrix();
	::glTranslated(translation.x(), translation.y(), 0);
	::glBegin(GL_TRIANGLE_FAN);
	renderVertex(domain.internalPoint());
	renderVertices(domain);
	renderHeadVertex(domain);
	::glEnd();
	::glPopMatrix();
}

void DebugRendererGL::renderWire(const IBounded2& domain, const Vector2& translation)
{
	::glPushMatrix();
	::glTranslated(translation.x(), translation.y(), 0);
	::glBegin(GL_LINE_LOOP);
	renderVertices(domain);
	::glEnd();
	::glPopMatrix();
}


void DebugRendererGL::renderHeadVertex(const IBounded2& domain)
{
	VALIDATE_STACK(*stack_);
	IEdgeIterator2* itEdge(domain.boundary(*stack_));
	IVertexIterator2* itVertex(itEdge->current().segmentate(tolerance_, *stack_));
	renderVertex(itVertex->point());
	stack_->destroy(itVertex);
	stack_->destroy(itEdge);
}

void DebugRendererGL::renderVertices(const IBounded2& domain)
{
	VALIDATE_STACK(*stack_);
	IEdgeIterator2* itEdge(domain.boundary(*stack_));
	do
	{
		VALIDATE_STACK(*stack_);
		IVertexIterator2* itVertex(itEdge->current().segmentate(tolerance_, *stack_));
		do
		{
			renderVertex(itVertex->point());
		} while (itVertex->next());
		stack_->destroy(itVertex);
	} while (itEdge->next());
	stack_->destroy(itEdge);
}


void DebugRendererGL::renderVertex(const Vector2& point)
{
	::glVertex2d(point.x(), point.y());
}